﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Snowdreamist.Runtime;
using Snowdreamist.Runtime.Services;

namespace Snowdreamist.Diagnostics
{
    public class Log : ILog, IModuleRuntimeServiceGenerator, IModuleRuntimeService
    {
        public const string DefaultName = "Default";

        public Log() : this(null) { }

        public Log(string name)
        {
            if (name == null)
                name = DefaultName;
            // init, TODO: add config to specify source level
            this._traceSource = new TraceSource(name, SourceLevels.All);
            // config
            if (SystemRuntime.Current.Configuration.Log.RuntimeLogWatcherEnabled)
            {
                // add stream watcher
            }
        }

        public virtual void Initialize() { }

        public void Write(TraceEventType eventType, int id, string message)
        {
            this._traceSource.TraceEvent(eventType, id, message);
        }

        public void Write(TraceEventType eventType, int id, string message, Exception error)
        {
            this._traceSource.TraceEvent(eventType, id, message + Environment.NewLine + error.ToString());
        }

        public IModuleRuntimeService GetModuleRuntimeService(IModuleDefinition definition, out Type serviceConrtactType)
        {
            serviceConrtactType = typeof(ILog);
            return new Log(definition.Name);
        }

        public virtual void OnRuntimeDisposing()
        {
            this.Write(TraceEventType.Information, (int)EventID.RuntimeStateChanged, "Runtime is disposing");
        }

        public void Initialize(ModuleRuntime runtime)
        {
            // module, nothing
            this.Write(TraceEventType.Information, (int)EventID.RuntimeStateChanged, "ModuleRuntime is Initializing");
        }

        public void Destroy(ModuleRuntime runtime)
        {
            // module, nothing
            this.Write(TraceEventType.Information, (int)EventID.RuntimeStateChanged, "ModuleRuntime is destroying");
        }

        #region private

        private TraceSource _traceSource;

        #endregion private
    }
}